<template>
  <div class="passwordStrengContainer">
    <div class="label">
      密码强度
    </div>
    <div class="passwordStrength">
      <div class="passwordStrengthBar" :style="{ backgroundColor: currentStrength>=0?'#19BE5C':'#F3F3F3' }"></div>
      <div class="passwordStrengthBar" :style="{ backgroundColor: currentStrength>=1?'#19BE5C':'#F3F3F3' }"></div>
      <div class="passwordStrengthBar" :style="{ backgroundColor: currentStrength>=2?'#19BE5C':'#F3F3F3' }"></div>
    </div>
    <div class="tip" :style="{ color: currentStrength>=2?'#19BE5C':'#bfbfbf' }">
      {{currentStrengthText}}
    </div>
  </div>
</template>

<script>
export default {
  name: "passwordStreng",
  props: {
    password: {
      type: String,
      required: true,
    },
  },
  watch: {
    password(newValue, oldValue) {
      this.checkStrength();
    },
  },
  data() {
    return {
      currentStrength: -1,
      currentStrengthColor: "#F3F3F3",
      currentStrengthText: "",
    };
  },
  methods: {
    checkStrength() {
      /**
       * 密码强度校验规则
       * */
      if (!this.password) {
        this.currentStrength = -1;
        this.currentStrengthColor = "#F3F3F3";
        this.currentStrengthText = "";
        return;
      }

      /*** 强密码：密码长度8个字符以上。密码包含3种字符类型（大写字母、小写字母、数字）。*/
      if (
        (this.password + "").length >= 8 &&
        this.isStrongPassword(this.password)
      ) {
        this.currentStrength = 2;
        this.currentStrengthColor = "#00D29A";
        this.currentStrengthText = "强";
        return;
      }

      if (
        (this.password + "").length >= 8 &&
        this.containsLetterAndNumber(this.password)
      ) {
        /** 中等密码：密码长度在8到11个字符之间。密码包含两种字符类型（字母和数字）。*/
        this.currentStrength = 1;
        this.currentStrengthColor = "#FF9539";
        this.currentStrengthText = "中";
        return;
      }

      if ((this.password + "").length < 8 || this.isMonoType(this.password)) {
        /**弱密码：密码长度少于8个字符。或者密码只包含一种字符类型（例如，全部是字母或者全部是数字）。*/
        this.currentStrength = 0;
        this.currentStrengthColor = "#F04646";
        this.currentStrengthText = "弱";
        return;
      }
    },
    // 判断字符串是否只有一种字符类型
    isMonoType(str) {
      // 使用正则表达式匹配字符串中的字符类型
      // \w 匹配任意字母数字下划线字符，等价于 [A-Za-z0-9_]
      // \W 匹配任意非单词字符
      // \s 匹配任意空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v\u00A0\u2028\u2029]
      // \S 匹配任意非空白字符
      // \d 匹配任意数字，等价于 [0-9]
      // \D 匹配任意非数字
      const regex =
        /^(\w)\1*$|^(\W)\1*$|^(\s)\1*$|^(\S)\1*$|^(\d)\1*$|^(\D)\1*$/;
      return regex.test(str);
    },

    // 判断字符串是否至少含有 字母和数字
    containsLetterAndNumber(str) {
      // 分别检测是否包含字母、数字、特殊符号
      const hasLetter = /[a-zA-Z]/.test(str);
      const hasNumber = /[0-9]/.test(str);
      const hasSpecialChar = /\W/.test(str); // 匹配非字母数字字符

      // 检查长度是否在 8 到 20 位之间
      const validLength = str.length >= 8 && str.length <= 20;

      // 至少符合两个条件
      const conditionsMet =
        [hasLetter, hasNumber, hasSpecialChar].filter(Boolean).length >= 2;

      return validLength && conditionsMet;
    },

    // 判断字符串至少要包含 数字， 大写字母，小写字母 这3种类型
    isStrongPassword(str) {
      return /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*\W)[A-Za-z0-9\W]{8,20}$/.test(str);
    },
  },
};
</script>

<style lang="scss" scoped>
.passwordStrengContainer {
  display: flex;
  padding: 0 0 23px;
  .label {
    // width: 56px;
    height: 19px;
    font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
      Microsoft YaHei, Arial, sans-serif;
    font-size: 14px;
    color: #bfbfbf;
    line-height: 19px;
    text-align: left;
    font-style: normal;
    padding-left: 12px;
    padding-right: 10px;
  }
  .passwordStrength {
    display: flex;
    align-items: center;
    .passwordStrengthBar {
      width: 59px;
      height: 3px;
      margin-right: 7px;
    }
    .tip {
    }
  }
}
</style>